package com.example.myapplication.found.model;

import com.example.myapplication.found.IndustryFound;
import com.example.myapplication.found.bean.KDJBean;
import com.example.myapplication.found.bean.StockBean;
import com.example.myapplication.found.bean.StockKlineBean;
import com.example.myapplication.found.contract.FenxiCallback;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author: rongfeng
 * @date: 2022/8/8
 * @description KDJ
 */
public class Fenxi4 extends BaseData {
    private StockBean dayStockBean;
    private StockBean weekStockBean;
    public List<StockKlineBean> dayKlineList;
    public List<StockKlineBean> weekKlineList;
    //9, 18,24
    private int n = 9;
    private float money = 10000;
    private FenxiCallback kdjCallback;
    List<KDJBean> kdjBeanList;
    List<KDJBean> weekKdjBeanList;

    public Fenxi4(StockBean stockBean, StockBean weekStockBean) {
        super(stockBean, weekStockBean);
        initKDJ();
    }


    public FenxiCallback getKdjCallback() {
        return kdjCallback;
    }

    public void setKdjCallback(FenxiCallback kdjCallback) {
        this.kdjCallback = kdjCallback;
    }

    public void initKDJ() {
        kdjBeanList = new ArrayList<>();
        float lastK = 50;
        float lastD = 50;
        for (int i = n; i <= dayKlineList.size(); i++) {
            List<StockKlineBean> tempList = dayKlineList.subList(i - n, i);
            float H = -1, L = 999999999;
            float C = tempList.get(n - 1).shouPan;
            for (StockKlineBean ben : tempList) {
                if (ben.zuigao > H) {
                    H = ben.zuigao;
                }
                if (ben.zuidi < L) {
                    L = ben.zuidi;
                }
            }
            float rsv = (C - L) / (H - L) * 100;
            lastK = getKValue(rsv, lastK);
            lastD = getDValue(lastD, lastK);
            float J = 3f * lastK - 2 * lastD;
            if (IndustryFound.isTest) {
//                System.out.println(weekKlineList.get(i - 1).date);
//                System.out.println(" k=" + (int) lastK + " d=" + (int) lastD + " j=" + (int) J);
            }
            kdjBeanList.add(new KDJBean(dayKlineList.get(i - 1), lastK, lastD, J));
        }


        weekKdjBeanList = new ArrayList<>();
        lastK = 50;
        lastD = 50;
        for (int i = n; i <= weekKlineList.size(); i++) {
            List<StockKlineBean> tempList = weekKlineList.subList(i - n, i);
            float H = -1, L = 999999999;
            float C = tempList.get(n - 1).shouPan;
            for (StockKlineBean ben : tempList) {
                if (ben.zuigao > H) {
                    H = ben.zuigao;
                }
                if (ben.zuidi < L) {
                    L = ben.zuidi;
                }
            }
            float rsv = (C - L) / (H - L) * 100;
            lastK = getKValue(rsv, lastK);
            lastD = getDValue(lastD, lastK);
            float J = 3f * lastK - 2 * lastD;
            if (IndustryFound.isTest) {
//                System.out.println(weekKlineList.get(i - 1).date);
//                System.out.println(" k=" + (int) lastK + " d=" + (int) lastD + " j=" + (int) J);
            }
            weekKdjBeanList.add(new KDJBean(weekKlineList.get(i - 1), lastK, lastD, J));
        }


    }

    public boolean isKdjPoint(String date) {
        boolean isDayPoint = false, isWeekPoint = false;
        KDJBean kdjBean = null;
        KDJBean weekKdjBean = null;
        for (KDJBean bean : kdjBeanList) {
            if (bean.stockKlineBean.date.equals(date)) {
                kdjBean = bean;
            }
        }
        if (kdjBean.j < 50 && kdjBean.j > kdjBean.k && kdjBean.k > kdjBean.d) {
            if (kdjBeanList.indexOf(kdjBean) - 1 >= 0 && kdjBeanList.get(kdjBeanList.indexOf(kdjBean) - 1).j < kdjBean.j) {
                if (IndustryFound.isTest) {
                    System.out.println("日" + kdjBean.stockKlineBean.date + " j=" + kdjBean.j + " k=" + kdjBean.k + " d=" + kdjBean.d);
                }
                isDayPoint = true;
            }
        }

        for (KDJBean weekKdj : weekKdjBeanList) {
            if (weekKdj.stockKlineBean.date.equals(kdjBean.stockKlineBean.date)) {
                if (weekKdjBeanList.indexOf(weekKdj) - 1 >= 0 && weekKdjBeanList.get(weekKdjBeanList.indexOf(weekKdj) - 1).j < weekKdj.j) {
                    weekKdjBean = weekKdj;
                    isWeekPoint = true;
                }
            }
        }

        if (isDayPoint && isWeekPoint) {
            if (IndustryFound.isTest) {
                System.out.println("周" + weekKdjBean.stockKlineBean.date + " j=" + weekKdjBean.j + " k=" + weekKdjBean.k + " d=" + weekKdjBean.d);
            }
        }
        return isDayPoint && isWeekPoint;
    }

    /**
     * 计算方法编辑
     * KDJ的计算比较复杂，首先要计算周期（n日、n周等）的RSV值，即未成熟随机指标值，然后再计算K值、D值、J值等。以n日KDJ数值的计算为例，其计算公式为
     * n日RSV=（Cn－Ln）/（Hn－Ln）×100
     * 公式中，Cn为第n日收盘价；Ln为n日内的最低价；Hn为n日内的最高价。
     * 其次，计算K值与D值：
     * 当日K值=2/3×前一日K值+1/3×当日RSV
     * 当日D值=2/3×前一日D值+1/3×当日K值
     * 若无前一日K 值与D值，则可分别用50来代替。
     * J值=3*当日K值-2*当日D值
     * 以9日为周期的KD线为例，即未成熟随机值，计算公式为
     * 9日RSV=（C－L9）÷（H9－L9）×100
     * 公式中，C为第9日的收盘价；L9为9日内的最低价；H9为9日内的最高价。
     * K值=2/3×第8日K值+1/3×第9日RSV
     * D值=2/3×第8日D值+1/3×第9日K值
     * J值=3*第9日K值-2*第9日D值
     * 若无前一日K
     * 值与D值，则可以分别用50代替。
     */
    public void start() {

        for (int i = 0; i < dayKlineList.size(); i++) {
            dayKlineList.get(i).index = i;
        }
        List<KDJBean> kdjBeanList = new ArrayList<>();
        List<KDJBean> dealList = new ArrayList<>();
        float lastK = 50;
        float lastD = 50;
        for (int i = n; i <= dayKlineList.size(); i++) {
            List<StockKlineBean> tempList = dayKlineList.subList(i - n, i);

            float H = -1, L = 999999999;
            float C = tempList.get(n - 1).shouPan;
            for (StockKlineBean ben : tempList) {
                if (ben.zuigao > H) {
                    H = ben.zuigao;
                }
                if (ben.zuidi < L) {
                    L = ben.zuidi;
                }
            }
            float rsv = (C - L) / (H - L) * 100;
            lastK = getKValue(rsv, lastK);
            lastD = getDValue(lastD, lastK);
            float J = 3f * lastK - 2 * lastD;
            if (IndustryFound.isTest) {
//                System.out.println(weekKlineList.get(i - 1).date);
//                System.out.println(" k=" + (int) lastK + " d=" + (int) lastD + " j=" + (int) J);
            }
            kdjBeanList.add(new KDJBean(dayKlineList.get(i - 1), lastK, lastD, J));
        }
//        //交叉点
        for (int i = 0; i < kdjBeanList.size(); i++) {
            KDJBean kdjBean = kdjBeanList.get(i);
            if (kdjBean.j < 50 && Math.abs(kdjBean.d - kdjBean.k) < 10 && Math.abs(kdjBean.j - kdjBean.k) < 10) {
                if (i - 1 >= 0 && kdjBeanList.get(i - 1).j < kdjBean.j) {
                    dealList.add(kdjBean);
                }
            }
        }
//
        int lastDealDay = 0;
        int dealCount = 0;
        boolean isBuy = false;
        boolean isSeal = false;
        //日交易
        for (int i = 0; i < kdjBeanList.size(); i++) {
            KDJBean kdjBean = kdjBeanList.get(i);
            if (kdjBean.j < 50 && kdjBean.j > kdjBean.k && kdjBean.k > kdjBean.d) {
                if (i - 1 >= 0 && kdjBeanList.get(i - 1).j < kdjBean.j) {
                    if (IndustryFound.isTest) {
                        System.out.println(kdjBean.stockKlineBean.date);
                        System.out.println(" j=" + kdjBean.j + " k=" + kdjBean.k + " d=" + kdjBean.d);
                    }
                    if (kdjBean.stockKlineBean.index + 1 > dayKlineList.size()) {
                        StockKlineBean nextBean = dayKlineList.get(kdjBean.stockKlineBean.index + 1);
                        money = money + (money * (nextBean.chg / 100));
                        if (IndustryFound.isTest) {
                            System.out.println(nextBean.date + " 涨跌 " + nextBean.chg);
                            System.out.println("money " + money);
                        }
                    }
                    dealCount++;
                    if (IndustryFound.isTest) {
                        System.out.println();
                    }
                }
            } else if (kdjBean.j > 50 && kdjBean.j < kdjBean.k && kdjBean.k < kdjBean.d) {

            }
        }

        //周交易
//        for (int i = 0; i < dealList.size(); i++) {
//            KDJBean kdjBean = dealList.get(i);
//            if (IndustryFound.isTest) {
//                System.out.println(kdjBean.stockKlineBean.date);
//                System.out.println(" k=" + (int) kdjBean.k + " d=" + (int) kdjBean.d + " j=" + (int) kdjBean.j);
//            }
//            for (int j = 0; j < dealDay; j++) {
//                int tagetIndex = weekKlineList.indexOf(kdjBean.stockKlineBean);
//                if (tagetIndex + j + 1 < kdjBeanList.size()) {
//                    int targetKline = 0;
//                    for (StockKlineBean klineBean : dayKlineList) {
//                        if (klineBean.date.equals(kdjBean.stockKlineBean.date)) {
//                            targetKline = klineBean.index;
//                        }
//                    }
//                    for (int k = 0; k < 5; k++) {
//                        if (targetKline + k + 1 < dayKlineList.size()) {
//                            StockKlineBean LastBean = dayKlineList.get(targetKline + k);
//                            StockKlineBean nextBean = dayKlineList.get(targetKline + k + 1);
//                            if (k > 0 && LastBean.shouPan < kdjBean.stockKlineBean.shouPan && nextBean.index > lastDealDay) {
//                                continue;
//                            }
//                            lastDealDay = nextBean.index;
//                            money = money + (money * (nextBean.chg / 100));
//                            if (IndustryFound.isTest) {
//                                System.out.println(nextBean.date + " 涨跌 " + nextBean.chg);
//                                System.out.println("money " + money);
//                            }
//                        }
//                    }
//                    dealCount++;
//                }
//            }
//
//            if (IndustryFound.isTest) {
//                System.out.println();
//            }
//        }

//        boolean isDeal = false;
//        float lowLimt = 0;
//        //周点，日交易
//        for (int i = 0; i < kdjBeanList.size(); i++) {
//            KDJBean kdjBean = kdjBeanList.get(i);
//            KDJBean nextKdjBean = null;
//            if (i + 1 < kdjBeanList.size()) {
//                nextKdjBean = kdjBeanList.get(i + 1);
//            }
//            if (kdjBean.j < 50 && kdjBean.j > kdjBean.k && kdjBean.k > kdjBean.d) {
//                if (i - 1 >= 0 && kdjBeanList.get(i - 1).j < kdjBean.j) {
//                    isDeal = true;
//                    lowLimt = kdjBean.stockKlineBean.shouPan;
//                    if (IndustryFound.isTest) {
//                        System.out.println("找到上涨金叉 ");
//                        System.out.println(kdjBean.stockKlineBean.date + " k=" + (int) kdjBean.k + " d=" + (int) kdjBean.d + " j=" + (int) kdjBean.j);
//                        System.out.println();
//                    }
//                }
//            }else {
//                isDeal = false;
//            }
//
//            //&& i - 1 >= 0 && kdjBeanList.get(i - 1).j > kdjBean.j
//            if (kdjBean.j > 85) {
//                isDeal = false;
//                if (IndustryFound.isTest) {
////                    System.out.println("找到下跌金叉 ");
////                    System.out.println(kdjBean.stockKlineBean.date + " k=" + (int) kdjBean.k + " d=" + (int) kdjBean.d + " j=" + (int) kdjBean.j);
////                    System.out.println();
//                }
//            }
//            if (isDeal) {
//                int startIndex = 0, endIndex = 0;
//                for (StockKlineBean klineBean : dayKlineList) {
//                    if (klineBean.date.equals(kdjBean.stockKlineBean.date)) {
//                        startIndex = klineBean.index;
//                    }
//                }
//
//                if (nextKdjBean != null) {
//                    for (StockKlineBean klineBean : dayKlineList) {
//                        if (klineBean.date.equals(nextKdjBean.stockKlineBean.date)) {
//                            endIndex = klineBean.index;
//                        }
//                    }
//                }
//
//
//
//                for (int j = startIndex; j < startIndex+1; j++) {
//                    StockKlineBean nextBean = dayKlineList.get(j + 1);
//                    StockKlineBean LastBean = dayKlineList.get(j);
//                    if (j > 0 && (LastBean.shouPan < lowLimt || nextBean.index <= lastDealDay)) {
//                        isDeal = false;
//                        break;
//                    }
//                    money = money + (money * (nextBean.chg / 100));
//                    lastDealDay = nextBean.index;
//                    if (IndustryFound.isTest) {
//                        System.out.println(nextBean.date + " 涨跌 " + nextBean.chg);
//                        System.out.println("money " + money);
//                    }
//                    dealCount++;
//                }
//            }
//
//        }
//
        System.out.println(dayStockBean.name + " " + dayStockBean.code);
        System.out.println("交易次数 " + dealCount + " 持有时长 " + dealCount);
        System.out.println("剩余金额 " + money);
        System.out.println();
        if (kdjCallback != null) {
            kdjCallback.fenxiCallback(1);
        }
    }


    public float getKValue(float rsv, float k) {
        return 2f / 3f * k + 1f / 3f * rsv;
    }

    public float getDValue(float d, float k) {
        return 2f / 3f * d + 1f / 3f * k;
    }

    public static void analysis() {

    }


}
